package server;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.net.Socket;
import java.util.Vector;
import uk.co.caprica.vlcj.player.headless.HeadlessMediaPlayer;
import uk.co.caprica.vlcj.test.VlcjTest;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;

public class hiloComando extends VlcjTest {

    private HeadlessMediaPlayer mediaPlayer;
    private MediaPlayerFactory mediaPlayerFactory;
    private Thread thread;
    private Socket socket;
    private DataInputStream dataIn;
    private DataOutputStream dataOut;
    private boolean flag;
    private long posicion;
    private long fulltime;
    private String confirm;
    private String options;
    private String path;
    private String namefile;
    private static String OK = "ok";
    private static String NOK = "nok";
    private static String TIMER = "timer";
    private static String NEWVIDEO = "new";
    private static String POSITION = "position";
    private static String SPOSITION = "sposition";
    private static String PLAY = "play";
    private static String PAUSE = "pause";
    private static String STOP = "stop";
    private static String CURRENT = "current";
    private static String LENGTH = "length";
    private static String QUIT = "quit";
    private static String EXIT = "exit";
    private static String QUALITY = "quality";
    private static String ULQ = "240p";
    private static String LQ = "360p";
    private static String SQ = "480p";
    private static String HQ = "720p";
    private static String option_1 = ":no-sout-rtp-sap";
    private static String option_2 = ":no-sout-standard-sap";
    private static String option_3 = ":sout-all"; 
    private static String option_4 = ":sout-keep";
    
    private Vector<String> qualities;
    private Vector<String> names;

    public hiloComando(String options, Socket socket, int ncliente) throws Exception {
        String media = "videos/prueba-240p.mp4"; // Video por defecto
        String[] argumentos = {""};
        this.options = options;
        this.posicion = 0;
        this.socket = socket;
        this.flag = true;
        dataIn = new DataInputStream(socket.getInputStream());
        dataOut = new DataOutputStream(socket.getOutputStream());
        dataOut.writeInt(ncliente);
        mediaPlayerFactory = new MediaPlayerFactory(argumentos);
        mediaPlayer = mediaPlayerFactory.newHeadlessMediaPlayer();
        mediaPlayer.prepareMedia(media, options, option_1, option_2, option_3, option_4);
        System.out.println("Cliente " + socket.getInetAddress() + " a iniciado conexion.");
        startThread();
    }

    public final void startThread() {
        thread = new Hilo();
        thread.start();
    }

    public class Hilo extends Thread {

        @Override
        public void run() {
            String comando = null;
            String s = null;
            String tok[];
            while (flag) {
                try {
                    comando = dataIn.readUTF();
                    System.out.println("comando"+comando);
                    tok = comando.split("\\b\\s");
                    s = tok[0];
                    if (s.equals(LENGTH)) {           // Longitud del video: [length]
                        System.out.println("Length.");
                        dataOut.writeLong(fulltime);
                    } else if (s.equals(TIMER)) {    // Posicion actual [timer]
                        posicion = mediaPlayer.getTime();
                        dataOut.writeLong(posicion);
                    } else if (s.equals(NEWVIDEO)) { // Cargar nuevo video: [new <namefile>]
                        System.out.println("Load new Video.");
                        namefile = tok[1].trim();
           
                        if (solicitar_archivoQ()) {
                            //consigo y mando calidades
                            int i =0;
                            for(i =0;i< qualities.size();i++){
                                System.out.println(qualities.elementAt(i));
                                dataOut.writeUTF(qualities.elementAt(i));
                            }
                            dataOut.writeUTF(".");
                            set_video();
            
                        }
                        dataOut.writeUTF(confirm);
                        System.out.println("confirmado");
                    } else if (s.equals(POSITION)) {  // Cambiar posicion del video: [position <hh:mm:ss>]
                        System.out.println("Position");
                        cambiar_posicion(tok[1].trim());
                    }else if (s.equals(SPOSITION)) {  // Cambiar posicion del video: [position <hh:mm:ss>]
                        System.out.println("SPosition");
                        cambiar_sposicion(tok[1].trim());
                    } else if (s.equals(QUALITY)) {   // Cambiar calidad del video: [quality <quality>]
                        System.out.println("Quality");
                        cambiar_calidadQ(tok[1].trim());
                        dataOut.writeUTF(confirm);
                    } else if (s.equals(PLAY)) {     // Reproducir archivo: [play]
                        System.out.println("Play");
                        mediaPlayer.play();
                    } else if (s.equals(PAUSE)) {    // Pausar reproduccion: [pause]
                        System.out.println("Pause");
                        mediaPlayer.pause();
                    } else if (s.equals(STOP)) {     // Detener reproduccion: [stop]
                        System.out.println("Stop");
                        mediaPlayer.stop();
                        posicion = 0;
                    } else if (s.equals(QUIT)) {    // Desconexion del cliente [quit]
                        flag = false;
                        mediaPlayer.stop();
                        System.out.println("Cliente " + socket.getInetAddress() + " a cerrado conexion.");
                        socket.close();
                    } else if (s.equals(EXIT)) {    // Cerrar programa servidor [exit]
                        System.out.println("Cerrando Servidor...");
                        System.exit(0);
                    } else if (s.equals(CURRENT)) {  // Posicion actual del video: [current]
                        System.out.println(mediaPlayer.getTime());
                    }
                } catch (ArrayIndexOutOfBoundsException e1) {
                    System.out.println("Error. Campo <namefile> no valido");
                    continue;
                } catch (Exception e) {
                    System.out.println("Error irrecuperable durante la comunicacion con el cliente.");
                    continue;
                }
            }
        }

        public String tiempo(long time) {
            long horas = time / 3600;
            long s1 = time % 3600;
            long minutos = s1 / 60;
            long segundos = s1 % 60;
            return (Long.toString(horas) + ":" + Long.toString(minutos) + ":" + Long.toString(segundos));
        }

        public long cambiar_formato(String time) {
            String tok[] = time.split("\\:");
            int horas = Integer.parseInt(tok[0].trim());
            int minutos = Integer.parseInt(tok[1].trim());
            int segundos = Integer.parseInt(tok[2].trim());
            long tiempo = ((horas * 3600) + (minutos * 60) + (segundos)) * 1000;
            return tiempo;
        }

        public void set_video() {
            try {
  
                posicion = 0;
                mediaPlayer.prepareMedia(path, options, option_1, option_2, option_3, option_4);
                mediaPlayer.play();
                Thread.sleep(500);
                fulltime = mediaPlayer.getLength();
                System.out.println("video setted");
            } catch (Exception ex) {
                System.out.println("Error ocurrido durante la carga del nuevo video.");
                confirm = NOK;
            }
        }

        public boolean solicitar_archivo() {
            File file;
            boolean is_file = false;
            path = "videos/" + namefile + "-" + ULQ + ".mp4"; // Cargar archivo. Por defecto el de mas baja calidad
            file = new File(path);
            is_file = file.isFile();
            if (is_file) {
                System.out.println("Load Video " + path);
                confirm = OK;
            } else {
                System.out.println("Video not found.");
                confirm = NOK;
            }
            return is_file;
        }
        
        public boolean solicitar_archivoQ() throws Exception {
            File file;
            boolean is_file = false;
            path = "videos/" + namefile; // 
            file = new File(path);
            is_file = file.isFile();
            if (is_file) {
                FileReader fr = new FileReader (file);
                BufferedReader br = new BufferedReader(fr);
                qualities = new Vector<String>();
                names = new Vector<String>();
                String linea;
                while((linea = br.readLine())!=null){
                    qualities.add(linea);
                    linea = br.readLine();
                    names.add(linea);            
               }
                
                path = "videos/" + names.elementAt(0);
                System.out.println("Load Video " + path);
                confirm = OK;
            } else {
                System.out.println("Video not found.");
                confirm = NOK;
            }
            return is_file;
        }

        public void cambiar_posicion(String time) {
            mediaPlayer.pause();
            long tiempo = 0;
            tiempo = cambiar_formato(time);
            mediaPlayer.setTime(tiempo);
        }

        public void cambiar_sposicion(String position) {
            mediaPlayer.pause();
            float pos2 = Float.parseFloat(position);
            mediaPlayer.setPosition(pos2);
        }
        
        public void cambiar_calidadQ(String quality) {
            long tiempo = posicion;
            int index = qualities.indexOf(quality);
            String name = names.get(index);
            path = "videos/" + name;
            set_videoquality();
            mediaPlayer.setTime(tiempo);
            mediaPlayer.pause();
        }
        public void cambiar_calidad(String quality) {
            long tiempo = posicion;
            path = "videos/" + namefile + "-" + quality + ".mp4";
            set_videoquality();
            mediaPlayer.setTime(tiempo);
            mediaPlayer.pause();
        }
        

        public void set_videoquality() {
            try {
                mediaPlayer.prepareMedia(path, options, option_1, option_2, option_3, option_4);
                mediaPlayer.play();
                Thread.sleep(500);
                confirm = OK;
            } catch (Exception ex) {
                System.out.println("Error ocurrido durante la carga del nuevo video.");
                confirm = NOK;
            }
        }
    }
}
